home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d927.lha / Telnet / src / tn3270.c < prev    next >
C/C++ Source or Header  |  1993-10-07  |  9KB  |  395 lines

  1. /*
  2.  * Copyright (c) 1988 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted provided
  6.  * that: (1) source distributions retain this entire copyright notice and
  7.  * comment, and (2) distributions including binaries display the following
  8.  * acknowledgement:  ``This product includes software developed by the
  9.  * University of California, Berkeley and its contributors'' in the
  10.  * documentation or other materials provided with the distribution and in
  11.  * all advertising materials mentioning features or use of this software.
  12.  * Neither the name of the University nor the names of its contributors may
  13.  * be used to endorse or promote products derived from this software without
  14.  * specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  16.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  17.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. #ifndef lint
  21. static char sccsid[] = "@(#)tn3270.c    5.1 (Berkeley) 9/14/90";
  22. #endif /* not lint */
  23.  
  24. #include <sys/types.h>
  25. #include <arpa/telnet.h>
  26.  
  27. #include "general.h"
  28.  
  29. #include "defines.h"
  30. #include "ring.h"
  31. #include "externs.h"
  32. #include "fdset.h"
  33.  
  34. #if    defined(TN3270)
  35.  
  36. #include "../ctlr/screen.h"
  37. #include "../general/globals.h"
  38.  
  39. #include "../telextrn.h"
  40. #include "../ctlr/externs.h"
  41.  
  42. #if    defined(unix)
  43. int
  44.     HaveInput,        /* There is input available to scan */
  45.     cursesdata,        /* Do we dump curses data? */
  46.     sigiocount;        /* Number of times we got a SIGIO */
  47.  
  48. char    tline[200];
  49. char    *transcom = 0;    /* transparent mode command (default: none) */
  50. #endif    /* defined(unix) */
  51.  
  52. char    Ibuf[8*BUFSIZ], *Ifrontp, *Ibackp;
  53.  
  54. static char    sb_terminal[] = { IAC, SB,
  55.             TELOPT_TTYPE, TELQUAL_IS,
  56.             'I', 'B', 'M', '-', '3', '2', '7', '8', '-', '2',
  57.             IAC, SE };
  58. #define    SBTERMMODEL    13
  59.  
  60. static int
  61.     Sent3270TerminalType;    /* Have we said we are a 3270? */
  62.  
  63. #endif    /* defined(TN3270) */
  64.  
  65.  
  66. void
  67. init_3270()
  68. {
  69. #if    defined(TN3270)
  70. #if    defined(unix)
  71.     HaveInput = 0;
  72.     sigiocount = 0;
  73. #endif    /* defined(unix) */
  74.     Sent3270TerminalType = 0;
  75.     Ifrontp = Ibackp = Ibuf;
  76.     init_ctlr();        /* Initialize some things */
  77.     init_keyboard();
  78.     init_screen();
  79.     init_system();
  80. #endif    /* defined(TN3270) */
  81. }
  82.  
  83.  
  84. #if    defined(TN3270)
  85.  
  86. /*
  87.  * DataToNetwork - queue up some data to go to network.  If "done" is set,
  88.  * then when last byte is queued, we add on an IAC EOR sequence (so,
  89.  * don't call us with "done" until you want that done...)
  90.  *
  91.  * We actually do send all the data to the network buffer, since our
  92.  * only client needs for us to do that.
  93.  */
  94.  
  95. int
  96. DataToNetwork(buffer, count, done)
  97. register char    *buffer;    /* where the data is */
  98. register int    count;        /* how much to send */
  99. int        done;        /* is this the last of a logical block */
  100. {
  101.     register int loop, c;
  102.     int origCount;
  103.  
  104.     origCount = count;
  105.  
  106.     while (count) {
  107.     /* If not enough room for EORs, IACs, etc., wait */
  108.     if (NETROOM() < 6) {
  109.         fd_set o;
  110.  
  111.         FD_ZERO(&o);
  112.         netflush();
  113.         while (NETROOM() < 6) {
  114.         FD_SET(net, &o);
  115.         (void) select(net+1, (fd_set *) 0, &o, (fd_set *) 0,
  116.                         (struct timeval *) 0);
  117.         netflush();
  118.         }
  119.     }
  120.     c = ring_empty_count(&netoring);
  121.     if (c > count) {
  122.         c = count;
  123.     }
  124.     loop = c;
  125.     while (loop) {
  126.         if (((unsigned char)*buffer) == IAC) {
  127.         break;
  128.         }
  129.         buffer++;
  130.         loop--;
  131.     }
  132.     if ((c = c-loop)) {
  133.         ring_supply_data(&netoring, buffer-c, c);
  134.         count -= c;
  135.     }
  136.     if (loop) {
  137.         NET2ADD(IAC, IAC);
  138.         count--;
  139.         buffer++;
  140.     }
  141.     }
  142.  
  143.     if (done) {
  144.     NET2ADD(IAC, EOR);
  145.     netflush();        /* try to move along as quickly as ... */
  146.     }
  147.     return(origCount - count);
  148. }
  149.  
  150.  
  151. #if    defined(unix)
  152. void
  153. inputAvailable()
  154. {
  155.     HaveInput = 1;
  156.     sigiocount++;
  157. }
  158. #endif    /* defined(unix) */
  159.  
  160. void
  161. outputPurge()
  162. {
  163.     (void) ttyflush(1);
  164. }
  165.  
  166.  
  167. /*
  168.  * The following routines are places where the various tn3270
  169.  * routines make calls into telnet.c.
  170.  */
  171.  
  172. /*
  173.  * DataToTerminal - queue up some data to go to terminal.
  174.  *
  175.  * Note: there are people who call us and depend on our processing
  176.  * *all* the data at one time (thus the select).
  177.  */
  178.  
  179. int
  180. DataToTerminal(buffer, count)
  181. register char    *buffer;        /* where the data is */
  182. register int    count;            /* how much to send */
  183. {
  184.     register int c;
  185.     int origCount;
  186.  
  187.     origCount = count;
  188.  
  189.     while (count) {
  190.     if (TTYROOM() == 0) {
  191. #if    defined(unix)
  192.         fd_set o;
  193.  
  194.         FD_ZERO(&o);
  195. #endif    /* defined(unix) */
  196.         (void) ttyflush(0);
  197.         while (TTYROOM() == 0) {
  198. #if    defined(unix)
  199.         FD_SET(tout, &o);
  200.         (void) select(tout+1, (fd_set *) 0, &o, (fd_set *) 0,
  201.                         (struct timeval *) 0);
  202. #endif    /* defined(unix) */
  203.         (void) ttyflush(0);
  204.         }
  205.     }
  206.     c = TTYROOM();
  207.     if (c > count) {
  208.         c = count;
  209.     }
  210.     ring_supply_data(&ttyoring, buffer, c);
  211.     count -= c;
  212.     buffer += c;
  213.     }
  214.     return(origCount);
  215. }
  216.  
  217.  
  218. /*
  219.  * Push3270 - Try to send data along the 3270 output (to screen) direction.
  220.  */
  221.  
  222. int
  223. Push3270()
  224. {
  225.     int save = ring_full_count(&netiring);
  226.  
  227.     if (save) {
  228.     if (Ifrontp+save > Ibuf+sizeof Ibuf) {
  229.         if (Ibackp != Ibuf) {
  230.         memcpy(Ibuf, Ibackp, Ifrontp-Ibackp);
  231.         Ifrontp -= (Ibackp-Ibuf);
  232.         Ibackp = Ibuf;
  233.         }
  234.     }
  235.     if (Ifrontp+save < Ibuf+sizeof Ibuf) {
  236.         (void)telrcv();
  237.     }
  238.     }
  239.     return save != ring_full_count(&netiring);
  240. }
  241.  
  242.  
  243. /*
  244.  * Finish3270 - get the last dregs of 3270 data out to the terminal
  245.  *        before quitting.
  246.  */
  247.  
  248. void
  249. Finish3270()
  250. {
  251.     while (Push3270() || !DoTerminalOutput()) {
  252. #if    defined(unix)
  253.     HaveInput = 0;
  254. #endif    /* defined(unix) */
  255.     ;
  256.     }
  257. }
  258.  
  259.  
  260. /* StringToTerminal - output a null terminated string to the terminal */
  261.  
  262. void
  263. StringToTerminal(s)
  264. char *s;
  265. {
  266.     int count;
  267.  
  268.     count = strlen(s);
  269.     if (count) {
  270.     (void) DataToTerminal(s, count);    /* we know it always goes... */
  271.     }
  272. }
  273.  
  274.  
  275. #if    ((!defined(NOT43)) || defined(PUTCHAR))
  276. /* _putchar - output a single character to the terminal.  This name is so that
  277.  *    curses(3x) can call us to send out data.
  278.  */
  279.  
  280. void
  281. _putchar(c)
  282. char c;
  283. {
  284. #if    defined(sun)        /* SunOS 4.0 bug */
  285.     c &= 0x7f;
  286. #endif    /* defined(sun) */
  287.     if (cursesdata) {
  288.     Dump('>', &c, 1);
  289.     }
  290.     if (!TTYROOM()) {
  291.     (void) DataToTerminal(&c, 1);
  292.     } else {
  293.     TTYADD(c);
  294.     }
  295. }
  296. #endif    /* ((!defined(NOT43)) || defined(PUTCHAR)) */
  297.  
  298. void
  299. SetIn3270()
  300. {
  301.     if (Sent3270TerminalType && my_want_state_is_will(TELOPT_BINARY)
  302.         && my_want_state_is_do(TELOPT_BINARY) && !donebinarytoggle) {
  303.     if (!In3270) {
  304.         In3270 = 1;
  305.         Init3270();        /* Initialize 3270 functions */
  306.         /* initialize terminal key mapping */
  307.         InitTerminal();    /* Start terminal going */
  308.         setconnmode(0);
  309.     }
  310.     } else {
  311.     if (In3270) {
  312.         StopScreen(1);
  313.         In3270 = 0;
  314.         Stop3270();        /* Tell 3270 we aren't here anymore */
  315.         setconnmode(0);
  316.     }
  317.     }
  318. }
  319.  
  320. /*
  321.  * tn3270_ttype()
  322.  *
  323.  *    Send a response to a terminal type negotiation.
  324.  *
  325.  *    Return '0' if no more responses to send; '1' if a response sent.
  326.  */
  327.  
  328. int
  329. tn3270_ttype()
  330. {
  331.     /*
  332.      * Try to send a 3270 type terminal name.  Decide which one based
  333.      * on the format of our screen, and (in the future) color
  334.      * capaiblities.
  335.      */
  336.     InitTerminal();        /* Sets MaxNumberColumns, MaxNumberLines */
  337.     if ((MaxNumberLines >= 24) && (MaxNumberColumns >= 80)) {
  338.     Sent3270TerminalType = 1;
  339.     if ((MaxNumberLines >= 27) && (MaxNumberColumns >= 132)) {
  340.         MaxNumberLines = 27;
  341.         MaxNumberColumns = 132;
  342.         sb_terminal[SBTERMMODEL] = '5';
  343.     } else if (MaxNumberLines >= 43) {
  344.         MaxNumberLines = 43;
  345.         MaxNumberColumns = 80;
  346.         sb_terminal[SBTERMMODEL] = '4';
  347.     } else if (MaxNumberLines >= 32) {
  348.         MaxNumberLines = 32;
  349.         MaxNumberColumns = 80;
  350.         sb_terminal[SBTERMMODEL] = '3';
  351.     } else {
  352.         MaxNumberLines = 24;
  353.         MaxNumberColumns = 80;
  354.         sb_terminal[SBTERMMODEL] = '2';
  355.     }
  356.     NumberLines = 24;        /* before we start out... */
  357.     NumberColumns = 80;
  358.     ScreenSize = NumberLines*NumberColumns;
  359.     if ((MaxNumberLines*MaxNumberColumns) > MAXSCREENSIZE) {
  360.         ExitString("Programming error:  MAXSCREENSIZE too small.\n",
  361.                                 1);
  362.         /*NOTREACHED*/
  363.     }
  364.     printsub('>', sb_terminal+2, sizeof sb_terminal-2);
  365.     ring_supply_data(&netoring, sb_terminal, sizeof sb_terminal);
  366.     return 1;
  367.     } else {
  368.     return 0;
  369.     }
  370. }
  371.  
  372. #if    defined(unix)
  373. settranscom(argc, argv)
  374.     int argc;
  375.     char *argv[];
  376. {
  377.     int i;
  378.  
  379.     if (argc == 1 && transcom) {
  380.        transcom = 0;
  381.     }
  382.     if (argc == 1) {
  383.        return;
  384.     }
  385.     transcom = tline;
  386.     (void) strcpy(transcom, argv[1]);
  387.     for (i = 2; i < argc; ++i) {
  388.         (void) strcat(transcom, " ");
  389.         (void) strcat(transcom, argv[i]);
  390.     }
  391. }
  392. #endif    /* defined(unix) */
  393.  
  394. #endif    /* defined(TN3270) */
  395.